package com.waikuai.shop.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.waikuai.shop.common.result.Result;
import com.waikuai.shop.dto.BatchIssueToUsersDTO;
import com.waikuai.shop.dto.CardExchangeRequest;
import com.waikuai.shop.dto.WelfareCardQueryDTO;
import com.waikuai.shop.entity.WelfareCard;
import com.waikuai.shop.service.WelfareCardService;
import com.waikuai.shop.vo.CardIssueResultVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;

/**
 * 额度卡控制器
 * @author waikuai
 */
@Slf4j
@RestController
@RequestMapping("/welfare-cards")
@RequiredArgsConstructor
@Validated
public class WelfareCardController {

    private final WelfareCardService welfareCardService;

    /**
     * 验证卡密并兑换到账户余额
     */
    @PostMapping("/exchange")
    public Result<Object> exchangeCard(@Valid @RequestBody CardExchangeRequest request, HttpServletRequest httpRequest) {
        try {
            Long userId = getUserIdFromToken(httpRequest);
            if (userId == null) {
                return Result.error("用户未登录");
            }

            Object result = welfareCardService.exchangeCard(request, userId);
            if (result != null) {
                log.info("额度卡兑换成功，用户ID: {}, 卡号: {}", userId, maskCardNumber(request.getCardNumber()));
                return Result.success("额度卡兑换成功，已存入您的账户余额", result);
            } else {
                return Result.error("额度卡兑换失败，请检查卡号和密码是否正确");
            }
        } catch (Exception e) {
            log.error("额度卡兑换失败，用户ID: {}, 卡号: {}, 错误: {}",
                getUserIdFromToken(httpRequest), maskCardNumber(request.getCardNumber()), e.getMessage(), e);
            return Result.error("额度卡兑换失败");
        }
    }

    /**
     * 获取用户的额度卡列表
     */
    @GetMapping("/my-cards")
    public Result<List<WelfareCard>> getUserCards(
            @RequestParam(required = false) Integer status,
            HttpServletRequest request) {
        try {
            Long userId = getUserIdFromToken(request);
            if (userId == null) {
                return Result.error("用户未登录");
            }

            List<WelfareCard> cards = welfareCardService.getUserCards(userId, status);
            log.info("获取用户额度卡列表成功，用户ID: {}, 数量: {}", userId, cards.size());
            return Result.success("获取额度卡列表成功", cards);
        } catch (Exception e) {
            log.error("获取用户额度卡列表失败: {}", e.getMessage(), e);
            return Result.error("获取额度卡列表失败");
        }
    }

    /**
     * 获取用户可用额度卡总额
     */
    @GetMapping("/available-amount")
    public Result<BigDecimal> getAvailableAmount(HttpServletRequest request) {
        try {
            Long userId = getUserIdFromToken(request);
            if (userId == null) {
                return Result.error("用户未登录");
            }

            BigDecimal amount = welfareCardService.sumAvailableAmountByUserId(userId);
            log.info("获取用户可用额度卡总额成功，用户ID: {}, 金额: {}", userId, amount);
            return Result.success("获取可用额度成功", amount);
        } catch (Exception e) {
            log.error("获取用户可用额度卡总额失败: {}", e.getMessage(), e);
            return Result.error("获取可用额度失败");
        }
    }

    /**
     * 分页查询额度卡列表（管理员功能）
     */
    @GetMapping("/admin")
    @Validated
    public Result<IPage<WelfareCard>> getCardPage(@Valid WelfareCardQueryDTO queryDTO) {
        try {
            IPage<WelfareCard> result = welfareCardService.getCardPage(queryDTO);

            log.info("分页查询额度卡列表成功，页码: {}, 页大小: {}, 总数: {}", 
                queryDTO.getCurrent(), queryDTO.getSize(), result.getTotal());
            return Result.success("查询额度卡列表成功", result);
        } catch (Exception e) {
            log.error("分页查询额度卡列表失败: {}", e.getMessage(), e);
            return Result.error("查询额度卡列表失败");
        }
    }

    /**
     * 批量生成额度卡（管理员功能）
     */
    @PostMapping("/admin/batch-generate")
    public Result<String> batchGenerateCards(
            @RequestParam @NotNull BigDecimal amount,
            @RequestParam @Min(1) Integer quantity,
            @RequestParam @Min(1) Integer expireDays,
            @RequestParam(required = false) String batchNo) {
        try {
            boolean result = welfareCardService.batchGenerateCards(amount, quantity, expireDays, batchNo);
            if (result) {
                log.info("批量生成额度卡成功，面额: {}, 数量: {}, 批次号: {}", amount, quantity, batchNo);
                return Result.success("批量生成额度卡成功");
            } else {
                return Result.error("批量生成额度卡失败");
            }
        } catch (Exception e) {
            log.error("批量生成额度卡失败: {}", e.getMessage(), e);
            return Result.error("批量生成额度卡失败");
        }
    }

    /**
     * 批量发放额度卡（管理员功能）
     */
    @PostMapping("/admin/batch-issue")
    public Result<String> batchIssueCards(
            @RequestParam @NotNull List<Long> cardIds,
            @RequestParam @NotNull Long userId) {
        try {
            boolean result = welfareCardService.batchIssueCards(cardIds, userId);
            if (result) {
                log.info("批量发放额度卡成功，卡片数量: {}, 用户ID: {}", cardIds.size(), userId);
                return Result.success("批量发放额度卡成功");
            } else {
                return Result.error("批量发放额度卡失败");
            }
        } catch (Exception e) {
            log.error("批量发放额度卡失败: {}", e.getMessage(), e);
            return Result.error("批量发放额度卡失败");
        }
    }

    /**
     * 批量更新额度卡状态（管理员功能）
     */
    @PutMapping("/admin/batch-status")
    public Result<String> batchUpdateCardStatus(
            @RequestParam @NotNull List<Long> cardIds,
            @RequestParam @NotNull Integer status) {
        try {
            boolean result = welfareCardService.updateCardStatusBatch(cardIds, status);
            if (result) {
                log.info("批量更新额度卡状态成功，卡片数量: {}, 新状态: {}", cardIds.size(), status);
                return Result.success("批量更新状态成功");
            } else {
                return Result.error("批量更新状态失败");
            }
        } catch (Exception e) {
            log.error("批量更新额度卡状态失败: {}", e.getMessage(), e);
            return Result.error("批量更新状态失败");
        }
    }

    /**
     * 根据批次号查询额度卡（管理员功能）
     */
    @GetMapping("/admin/batch/{batchNo}")
    public Result<List<WelfareCard>> getCardsByBatchNo(@PathVariable String batchNo) {
        try {
            List<WelfareCard> cards = welfareCardService.getCardsByBatchNo(batchNo);
            log.info("根据批次号查询额度卡成功，批次号: {}, 数量: {}", batchNo, cards.size());
            return Result.success("查询批次额度卡成功", cards);
        } catch (Exception e) {
            log.error("根据批次号查询额度卡失败，批次号: {}, 错误: {}", batchNo, e.getMessage(), e);
            return Result.error("查询批次额度卡失败");
        }
    }

    /**
     * 获取即将过期的额度卡列表（管理员功能）
     */
    @GetMapping("/admin/expiring-soon")
    public Result<List<WelfareCard>> getCardsExpiringSoon(
            @RequestParam(defaultValue = "7") Integer days) {
        try {
            List<WelfareCard> cards = welfareCardService.getCardsExpiringSoon(days);
            log.info("获取即将过期的额度卡成功，天数: {}, 数量: {}", days, cards.size());
            return Result.success("获取即将过期额度卡成功", cards);
        } catch (Exception e) {
            log.error("获取即将过期的额度卡失败: {}", e.getMessage(), e);
            return Result.error("获取即将过期额度卡失败");
        }
    }

    /**
     * 统计各状态的额度卡数量（管理员功能）
     */
    @GetMapping("/admin/statistics")
    public Result<Object> getCardStatistics() {
        try {
            // 统计各状态的卡片数量
            Object statistics = new Object() {
                public final int undistributed = welfareCardService.countCardsByStatus(0);
                public final int distributed = welfareCardService.countCardsByStatus(1);
                public final int redeemed = welfareCardService.countCardsByStatus(2);
                public final int expired = welfareCardService.countCardsByStatus(3);
            };

            log.info("获取额度卡统计成功");
            return Result.success("获取额度卡统计成功", statistics);
        } catch (Exception e) {
            log.error("获取额度卡统计失败: {}", e.getMessage(), e);
            return Result.error("获取额度卡统计失败");
        }
    }

    /**
     * 验证额度卡是否可用
     */
    @PostMapping("/validate")
    public Result<String> validateCard(@Valid @RequestBody CardExchangeRequest request) {
        try {
            boolean isAvailable = welfareCardService.checkCardAvailable(request.getCardNumber(), request.getCardPassword());
            if (isAvailable) {
                log.info("验证额度卡成功，卡号: {}", maskCardNumber(request.getCardNumber()));
                return Result.success("额度卡验证成功");
            } else {
                return Result.error("额度卡不可用或已过期");
            }
        } catch (Exception e) {
            log.error("验证额度卡失败，卡号: {}, 错误: {}", maskCardNumber(request.getCardNumber()), e.getMessage(), e);
            return Result.error("验证额度卡失败");
        }
    }

    /**
     * 下载Excel模板（管理员功能）
     */
    @GetMapping("/admin/download-template")
    public void downloadTemplate(HttpServletResponse response) {
        try {
            welfareCardService.downloadTemplate(response);
            log.info("Excel模板下载成功");
        } catch (Exception e) {
            log.error("下载Excel模板失败: {}", e.getMessage(), e);
            try {
                response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                response.setContentType("application/json;charset=UTF-8");
                response.getWriter().write("{\"code\":500,\"message\":\"下载模板失败\"}");
            } catch (Exception ignored) {
            }
        }
    }

    /**
     * Excel导入并发放额度卡（管理员功能）
     */
    @PostMapping("/admin/import-issue")
    public Result<CardIssueResultVO> importAndIssueCards(@RequestParam("file") MultipartFile file) {
        try {
            CardIssueResultVO result = welfareCardService.importAndIssueCards(file);
            log.info("Excel导入发放完成，总数: {}, 成功: {}, 失败: {}", 
                result.getTotal(), result.getSuccessCount(), result.getFailCount());
            return Result.success("导入发放完成", result);
        } catch (Exception e) {
            log.error("Excel导入发放失败: {}", e.getMessage(), e);
            return Result.error("Excel导入失败: " + e.getMessage());
        }
    }

    /**
     * 多选员工批量发放额度卡（管理员功能）
     */
    @PostMapping("/admin/batch-issue-users")
    public Result<CardIssueResultVO> batchIssueToUsers(@Valid @RequestBody BatchIssueToUsersDTO dto) {
        try {
            Integer countPerUser = dto.getCardCount() != null ? dto.getCardCount() : 1;
            CardIssueResultVO result = welfareCardService.batchIssueToUsers(
                dto.getUserIds(), dto.getCardAmount(), countPerUser);
            
            log.info("批量发放完成，员工数: {}, 成功: {}, 失败: {}", 
                result.getTotal(), result.getSuccessCount(), result.getFailCount());
            return Result.success("批量发放完成", result);
        } catch (Exception e) {
            log.error("批量发放失败: {}", e.getMessage(), e);
            return Result.error("批量发放失败: " + e.getMessage());
        }
    }

    /**
     * 获取员工的额度卡详情（普通员工看到部分隐藏的卡密）
     */
    @GetMapping("/my-cards-detail")
    public Result<List<WelfareCard>> getMyCardsDetail(@RequestParam(required = false) Integer status, 
            HttpServletRequest request) {
        try {
            Long userId = getUserIdFromToken(request);
            if (userId == null) {
                return Result.error("用户未登录");
            }

            List<WelfareCard> cards = welfareCardService.getMyCardsWithCredentials(userId, status);
            
            // 对普通员工隐藏卡密（前4位+****+后4位）
            cards.forEach(card -> {
                if (card.getCardNumber() != null) {
                    card.setCardNumber(maskCardCredential(card.getCardNumber()));
                }
                if (card.getCardPassword() != null) {
                    card.setCardPassword(maskCardCredential(card.getCardPassword()));
                }
            });
            
            log.info("获取员工额度卡详情成功，用户ID: {}, 数量: {}", userId, cards.size());
            return Result.success("获取额度卡详情成功", cards);
        } catch (Exception e) {
            log.error("获取员工额度卡详情失败: {}", e.getMessage(), e);
            return Result.error("获取额度卡详情失败");
        }
    }

    /**
     * 从请求中获取用户ID
     */
    private Long getUserIdFromToken(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            // 这里暂时返回一个测试用户ID
            return 2L; // 测试用户ID
        }
        return null;
    }

    /**
     * 隐藏卡号敏感信息
     */
    private String maskCardNumber(String cardNumber) {
        if (cardNumber == null || cardNumber.length() <= 8) {
            return "****";
        }
        return cardNumber.substring(0, 4) + "****" + cardNumber.substring(cardNumber.length() - 4);
    }

    /**
     * 部分隐藏卡号/密码（显示前4位和后4位）
     */
    private String maskCardCredential(String credential) {
        if (credential == null || credential.length() <= 8) {
            return "****";
        }
        return credential.substring(0, 4) + "****" + credential.substring(credential.length() - 4);
    }
}